using System;
using System.Collections.Generic;
using System.Text;

using Deepcode.Flux.Core.Systems.Workflow;
using Deepcode.Flux.Core.Systems.Workflow.Attribs;
using Deepcode.Flux.Core.Systems.Workflow.BaseHandlers;
using Deepcode.Flux.Core.Systems.Workflow.Bases;
using Deepcode.Flux.Core.Systems.Workflow.Enums;
using Deepcode.Flux.Core.Systems.Workflow.Info;
using Deepcode.Flux.Core.Systems.Security;
using Example.Workflow.Objects;


namespace Example.Workflow
{
	/// <summary>
	/// This is the example code for our workflow handler
	/// </summary>
	public class WFHandler : Deepcode.Flux.Core.Systems.Workflow.BaseHandlers.FluxBaseHandler
	{
		/// <summary>
		/// Exposes the data dictionary information to a workflow method
		/// </summary>
		/// <returns></returns>
		public override WorkflowDataDictionaryDescriptor GetDataDictionary()
		{
			WorkflowDataDictionaryDescriptor Dic = new WorkflowDataDictionaryDescriptor();
			Dic.Add("PK_ID", "The Unique Identifier of this telephone book entry");
			Dic.Add("Name", "The Name of the person in the telephone book");
			Dic.Add("Tel", "The telephone number of the person in the book");
			Dic.Add("Notes", "The notes about the person in the book");
			Dic.Add("SuperUserEmail", "The email address of a super user within Flux.NET");
			return Dic;
		}
		/// <summary>
		/// Cache of the telephone book object for data dictionary
		/// </summary>
		private TelephoneBookEntry _TeleBook = null;
		private TelephoneBookEntry GetTeleBook(int DataID)
		{
			// If our book is null, or if it's not null, but doesnt match the data ID, reload it
			if (((_TeleBook != null) && (_TeleBook.PK_ID != DataID)) || (_TeleBook == null))
			{
				TelephoneBook tb = new TelephoneBook();
				_TeleBook = tb.GetTelephoneBookByID(DataID);
			}
			if (_TeleBook == null) return null;
			return _TeleBook;
		}
		/// <summary>
		/// Retrieve value from a data dictionary
		/// </summary>
		/// <param name="Key"></param>
		/// <param name="DataID"></param>
		/// <returns></returns>
		public override string DataDictionaryItem(string Key, int DataID)
		{
			TelephoneBookEntry	Book = GetTeleBook(DataID);
			if (Book == null) return "";
			switch (Key)
			{
				case "PK_ID":
					return Book.PK_ID.ToString();
				case "Name":
					return Book.Name;
				case "Tel":
					return Book.Tel;
				case "Notes":
					return Book.Notes;
				case "SuperUserEmail":
					return "tony@deepcode.co.uk";
			}
			return "";
		}
		/// <summary>
		/// Override the CanBeDeleted function. Do normal checks
		/// and then ensure no TelephoneBook entries have the definition
		/// associated with it.
		/// </summary>
		/// <param name="DefinitionID"></param>
		/// <returns></returns>
		public override bool CanBeDeleted(int DefinitionID)
		{
			// Ensure definition not attached to a record
			TelephoneBook book = new TelephoneBook();
			if (book.GetAllTelephoneBookForWF(DefinitionID).Length > 0) return false;
			// Fallback to default checks
			return base.CanBeDeleted(DefinitionID);
		}
		/// <summary>
		/// Implement functionality to obtain a VIEW url for the data object
		/// </summary>
		/// <param name="Task"></param>
		/// <returns></returns>
		public override string GetViewURL(Task task)
		{
			return String.Format("~/extensions/exampleworkflow/Forms/ui_WFViewForm.aspx?ID={0}&TaskID={1}", task.FK_DataID, task.PK_ID);
		}
		/// <summary>
		/// Implement functionality to obtain an EDIT url for the data object
		/// </summary>
		/// <param name="Task"></param>
		/// <returns></returns>
		public override string GetEditURL(Task task)
		{
			return String.Format("~/extensions/exampleworkflow/Forms/ui_WFEditForm.aspx?ID={0}&TaskID={1}", task.FK_DataID, task.PK_ID);
		}
		/// <summary>
		/// This action will set the address book entry to valid
		/// </summary>
		[WorkflowMethod("Set address book entry valid")]
		public void SetStateValid(WorkflowEngine Engine, int ProcessID, int DataID, string DataName, string PropertyBag)
		{
			TelephoneBook book = new TelephoneBook();
			TelephoneBookEntry tel = book.GetTelephoneBookByID( DataID );
			if (tel == null) return;
			tel.State = 1;
			book.Save( tel );
		}
		/// <summary>
		/// This action will delete the address book entry
		/// </summary>
		[WorkflowMethod("Delete the address book entry")]
		public void DeleteRecord(WorkflowEngine Engine, int ProcessID, int DataID, string DataName, string PropertyBag)
		{
			// Removes the record because it's invalid
			TelephoneBook book = new TelephoneBook();
			book.DeleteByID( DataID );
		}
		/// <summary>
		/// This action will collect approval history data and add it to the 
		/// approval history field.
		/// </summary>
		[WorkflowMethodUI("Add Approval History Note")]
		public string ApprovalHistory(WorkflowEngine Engine, int TaskID, int ExitPathID)
		{
			return String.Format("~/extensions/exampleworkflow/Forms/ui_WFAddHistory.aspx?TaskID={0}&ExitID={1}", TaskID, ExitPathID);
		}
		/// <summary>
		/// This special taskable method raises a task for every user on the system!
		/// </summary>
		[WorkflowTaskableMethod("Everyone on the system")]
		public int[] TaskEveryone(WorkflowEngine Engine, UserCallbackType Type, int ProcessID, int DataID, string DataName)
		{
			if (Type == UserCallbackType.REQUEST_USERS)
			{
				List< int > items = new List<int>();
				AdministrationUsers users = new AdministrationUsers();
				foreach( AdministrationUser u in users.GetAllUsers() )
					items.Add( u.PK_ID );
				return items.ToArray();
			}
			if (Type == UserCallbackType.REQUEST_GROUPS)
			{
				List< int > items = new List<int>();
				AdministrationGroups groups = new AdministrationGroups();
				foreach( AdministrationGroup g in groups.GetAllGroups() )
					items.Add( g.PK_ID );

				return items.ToArray();
			}
			return null;
		}
	}
}
